package com.jdk.demo.unsafe.simple;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

/**大数组
Java的数组最大容量受常量Integer.MAX_VALUE的限制，如果我们用直接申请内存的方式去创建数组，那么数组大小只会收到堆的大小的限制。
 * @author zhangsulei
 *
 */
public class BigArray {

	private static Unsafe unsafe;

	public static void main(String[] args) throws Exception {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        unsafe = (Unsafe) f.get(null);
        // 设置数组大小为Integer.MAX_VALUE的2倍
        long SUPER_SIZE = (long) Integer.MAX_VALUE * 2;
        SuperArray array = new SuperArray(SUPER_SIZE);
        System.out.println("Array size:" + array.size()); // 4294967294
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            array.set((long) Integer.MAX_VALUE + i, (byte) 3);
            sum += array.get((long) Integer.MAX_VALUE + i);
        }
        System.out.println("Sum of 100 elements:" + sum);  // 300
    }

    private static Unsafe getUnsafe() {
        return unsafe;
    }

    static class SuperArray {
        private final static int BYTE = 1;
        private long size;
        private long address;

        public SuperArray(long size) {
            this.size = size;
            address = getUnsafe().allocateMemory(size * BYTE);
        }
        public void set(long i, byte value) {
            getUnsafe().putByte(address + i * BYTE, value);
        }
        public int get(long idx) {
            return getUnsafe().getByte(address + idx * BYTE);
        }
        public long size() {
            return size;
        }
    }

}
